package main

import (
	"fmt"
	"sync"
	"sync/atomic"
	"time"
)
/*
https://blog.csdn.net/qq_39920531/article/details/97646901
 */
var GlobalInt int64

var WG sync.WaitGroup

var ThreadCnt int

func AtomicOpr() {
	var TempInt int64
	for {
		//等待所有协程启动完成，模拟并发问题
		if ThreadCnt == 100 {
			break
		}
	}
	//错误写法
	//TempInt = GlobalInt
	//Result := atomic.CompareAndSwapInt64(&GlobalInt, TempInt, TempInt + 1)
	//fmt.Println(TempInt, " Try to CAS: " ,Result)
	//正确写法
	for {
		TempInt = atomic.LoadInt64(&GlobalInt)
		Result := atomic.CompareAndSwapInt64(&GlobalInt, TempInt, TempInt+1)
		if Result == true {
			fmt.Println(TempInt, " Try to CAS: ", Result)
			break
		}
	}
	WG.Done()
}

func main() {
	GlobalInt = 0
	ThreadCnt = 0
	fmt.Printf("The beginnig, ThreadCnt is:%d, GlobalInt:%d\n", ThreadCnt, GlobalInt)
	for i := 0; i < 100; i++ {
		go AtomicOpr()
		WG.Add(1)
		ThreadCnt += 1
		fmt.Println("ThreadCnt is: ", ThreadCnt)
	}
	WG.Wait()
	fmt.Printf("The end, ThreadCnt is:%d, GlobalInt:%d\n", ThreadCnt, GlobalInt)

	time.Sleep(time.Second * 2)
}
